package view;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;

import Serveur.Reservation;

import Both.Billet;
import Both.Passager;
import Both.ProfilPassager;
import Both.Trajet;
import Both.TypeBillet;
import Both.Ville;

import controleur.ActionReserver;
import controleur.ToutFenetre;

//boite de dialogue pour confirmer (ou infirmer) fermeture de l'application
public class FenetreReservation extends JDialog {
    private JButton reserver;

    private Label[] message;
    private Label[] message2;
    private Label[] monTab;
    private Choice[] monTabChoice;
    private Label message3;
    private ArrayList<ArrayList<JCheckBox>> monTabOption;
    private ToutFenetre monTout;
    private Choice c;
    private JSeparator[] separator;

    public FenetreReservation(ToutFenetre tout) {
        // Appel constructeur de la classe Dialog (dont on herite) => super(...)
        // On fixe le titre du bandeau de la fenetre mere
        // on indique "modal" (on ne peut rien faire d'autre avant d'avoir ferme
        // le Dialog)
        super(tout.maFenetre1, "Reservation", true);
        this.monTout = tout;
        this.setDefaultCloseOperation(1);
        if (!tout.maFenetre1.getDirect()) {
            monTab = new Label[tout.maFenetre1.getLisTrajetSelection().size()];
        } else {
            monTab = new Label[1];
        }
        message = new Label[monTab.length];
        message2 = new Label[monTab.length];
        monTabChoice = new Choice[monTab.length];
        separator = new JSeparator[monTab.length];
        monTabOption = new ArrayList<ArrayList<JCheckBox>>();
        Initialiser();
    }

    // Initialiser la fenêtre :
    private void Initialiser() {
        // Création et positionnement de tous les composants
        this.setResizable(false); // la fenêtre ne peut pas être retaillée par
                                  // l'utilisateur
        this.setLayout(new GridBagLayout());
        this.setMinimumSize(new Dimension(750, 400));

        /*
         * Ajout de ces composants en spécifiant les contraintes de type
         * GridBagConstraints.
         */
        GridBagConstraints gbc = new GridBagConstraints();
        remplirTabOption();
        for (int i = 0; i < monTab.length; i++) {

            message[i] = new Label("Cb de places?");
            /*
             * a- ajout du label contenant la specification du groupe que l'on
             * veux avoir.
             */
            gbc.gridx = 2;
            gbc.gridy = i * 3;
            gbc.gridwidth = gbc.gridheight = 1;
            gbc.insets = new Insets(0, 5, 0, 0);
            gbc.anchor = GridBagConstraints.BASELINE_LEADING;
            this.add(message[i], gbc);
            /* ************************************************************************************** */
            message2[i] = new Label("type de transport : "
                    + monTout.maFenetre1.getLisTrajetSelection().get(i)
                            .getTransport().getType().getTransportString());
            /*
             * a- ajout du label contenant la specification du groupe que l'on
             * veux avoir.
             */
            gbc.gridx = 1;
            gbc.gridy = i * 3;
            gbc.gridwidth = gbc.gridheight = 1;
            gbc.insets = new Insets(0, 5, 0, 0);
            gbc.anchor = GridBagConstraints.BASELINE_LEADING;
            this.add(message2[i], gbc);
            /* ************************************************************************************** */

            monTab[i] = new Label("trajet : "
                    + monTout.maFenetre1.getLisTrajetSelection().get(i)
                            .getVilleDepart().getVille()
                    + "-"
                    + monTout.maFenetre1.getLisTrajetSelection().get(i)
                            .getVilleArrive().getVille());
            /*
             * a-1- ajout du label contenant la specification du groupe que l'on
             * veux avoir.
             */
            gbc.gridx = 0;
            gbc.gridy = i * 3;
            gbc.gridwidth = gbc.gridheight = 1;
            gbc.insets = new Insets(0, 5, 0, 0);
            gbc.anchor = GridBagConstraints.BASELINE;
            this.add(monTab[i], gbc);
            // **************************************************************************************

            monTabChoice[i] = new Choice();

            monTabChoice[i].add("--");
            int n = monTout.maFenetre1.getLisTrajetSelection().get(i)
                    .getNbPlaceDispo();
            for (int j = 1; j <= n; j++) {
                monTabChoice[i].add("" + j);
            }

            // a-1- ajout du label contenant la specification du groupe que l'on
            // veux avoir.
            gbc.gridx = 3;
            gbc.gridy = i * 3;
            gbc.gridwidth = gbc.gridheight = 1;
            gbc.insets = new Insets(0, 5, 0, 0);
            gbc.anchor = GridBagConstraints.BASELINE;
            this.add(monTabChoice[i], gbc);
            // **************************************************************************************
            for (int j = 0; j < monTabOption.get(i).size(); j++) {
                // a-1- ajout du label contenant la specification du groupe que
                // l'on veux avoir.
                gbc.gridx = j + 1;
                gbc.gridy = i * 3 + 1;
                gbc.gridwidth = gbc.gridheight = 1;
                gbc.insets = new Insets(0, 5, 0, 0);
                gbc.anchor = GridBagConstraints.BASELINE;
                this.add(monTabOption.get(i).get(j), gbc);
                // **************************************************************************************

            }
            separator[i] = new JSeparator();
            /* s- Un séparateur. */
            gbc.gridy = i * 3 + 2;
            gbc.gridx = 0;
            gbc.gridwidth = 4;
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(5, 5, 0, 5);
            this.add(separator[i], gbc);
            /* ************************************************************************************** */

        }
        message3 = new Label("Effectuer la reservation ?");
        /*
         * a- ajout du label contenant la specification du groupe que l'on veux
         * avoir.
         */
        gbc.gridx = 0;
        gbc.gridy = (monTab.length + 1) * 3;
        gbc.insets = new Insets(0, 5, 0, 0);
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        this.add(message3, gbc);
        /* ************************************************************************************** */

        reserver = new JButton("Reserver");
        reserver
                .addActionListener(new ActionValiderReserver(this.monTout, this));
        reserver.setPreferredSize(new Dimension(30, 30));
        /* s- Un séparateur. */
        gbc.gridy = (monTab.length + 1) * 3 + 1;
        gbc.gridx = 0;
        gbc.insets = new Insets(0, 5, 0, 0);
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        this.add(reserver, gbc);
        /* ************************************************************************************** */
    }

    /**
     * Rempli la liste des services disponibles pour chaque trajet
     */
    private void remplirTabOption() {
        // Obtenir une reference sur la liste des trajets
        //
        ArrayList<Trajet> trajets = monTout.maFenetre1.getLisTrajetSelection();

        // Parcourir la liste des trajets
        // Pour chaque trajet, on recupere la grille des services disponibles
        // sous forme de HashMap
        // Puis on l'insere sous forme de liste de JCheckBox dans monTabOption
        //
        for (Trajet trajet : trajets) {
            // Creer la liste qui va contenir les JCheckBox pour le trajet
            // courrant
            //
            ArrayList<JCheckBox> currentList = new ArrayList<JCheckBox>();

            // Recuperer la grille des services disponibles
            //
            HashMap<String, Double> currentServices = trajet.getTransport()
                    .getType().getServicesDisponibles();

            // Verifier que des services sont bien disponibles pour le trajet
            // courrant
            //
            if (currentServices == null) {
                // Ajouter la liste courrante a la liste englobant tous les
                // JCheckBox
                //
                monTabOption.add(currentList);
                continue;
            }

            // Parcourir la grille
            // Pour chaque ligne du dictionnaire, recupere la cle et l'associe
            // et creer la JCheckBox correspondante
            // Puis l'ajouter a la liste courrante
            //
            for (String key : currentServices.keySet()) {
                JCheckBox currentBox = new JCheckBox(key + " : "
                        + currentServices.get(key) + " euros", false);
                currentBox.setActionCommand(key + "/"
                        + currentServices.get(key));
                currentList.add(currentBox);
            }

            // Ajouter la liste courrante a la liste englobant tous les
            // JCheckBox
            //
            monTabOption.add(currentList);
        }
    }

    public ArrayList<ArrayList<JCheckBox>> getMonTabOption() {
        return this.monTabOption;
    }

    public Choice[] getMonTabChoice() {
        return monTabChoice;
    }
}

class ActionRetour implements ActionListener {
    // pour fermer la fenetre avec le bouton "OK"
    FenetreReservation d;

    public ActionRetour(FenetreReservation d) {
        this.d = d;
    }

    public void actionPerformed(ActionEvent a) {
        d.dispose();
    }
}

class ActionQuitterOuiNon implements ActionListener {
    public void actionPerformed(ActionEvent a) {
        System.exit(0);
    }
}

class ActionValiderReserver implements ActionListener {

    private ToutFenetre tout;
    private FenetreReservation resa;

    public ActionValiderReserver(ToutFenetre tout, FenetreReservation resa) {
        this.tout = tout;
        this.resa = resa;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        ArrayList<ArrayList<JCheckBox>> options = resa.getMonTabOption();
        HashMap<String, Double> services = new HashMap<String, Double>();

        // Obtenir les services selectionne
        for (ArrayList<JCheckBox> listeServices : options) {
            for (JCheckBox b : listeServices) {
                if (b.isSelected()) {
                    String params[] = b.getActionCommand().split("/");
                    services.put(params[0], Double.valueOf(params[1]));
                }
            }

        }

        // Obtenir le nombre de place
        int nbPlace = resa.getMonTabChoice()[0].getSelectedIndex();

        if (nbPlace > 0) {
            Billet b = new Billet(tout.maFenetre1.getLisTrajetSelection(),
                    ProfilPassager.ADULTE, TypeBillet.NON_REMBOURSABLE,
                    services, nbPlace);
            b.genererRecapHTML();

            // Ajouter le passager au serveur
            Passager p = new Passager();
            p.ajouterBillet(b);

            // Ajouter la reservation au serveur
            for (Trajet t : tout.maFenetre1.getLisTrajetSelection()) {
                Reservation r = new Reservation(t, nbPlace);
                tout.monServeur.addReservation(r);
            }

            JOptionPane.showMessageDialog(this.resa,
                    "Merci pour votre réservation !", "",
                    JOptionPane.CLOSED_OPTION);

            this.resa.setVisible(false);
        } else {
            JOptionPane.showMessageDialog(this.resa,
                    "Veulliez selectionner le nombre de place !", "",
                    JOptionPane.ERROR_MESSAGE);
        }

    }

}
